package com.travelsky.server.chat_socket;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import com.travelsky.server.vo.group.Config;

/**
 * 服务器线程类
 ******************************************
 * @author HuangFeng  [2017年7月5日 下午12:54:40]
 * @version 1.0
 ******************************************
 */
public class ServerThread{

	public Server server;
	public BroadCast broadcast;
	public String lockTokenUser;;
	public List<String> waitQueue = new ArrayList<String>();
	public Vector<String> messages;
	public Vector<ClientThread> clients;
	public Map<Integer, String> users;  //用户
	private HttpClientThread httpClientThread;
	private TimerManager timerManager;
	public Config config;
	public String groupName;
	
	/**
	 * 构造方法
	 ******************************************
	 * @author HuangFeng [2017年7月5日 下午12:55:57]
	 * @version 1.0
	 ******************************************
	 */
	public ServerThread(Server server,String groupName){
		this.server = server;
		this.groupName = groupName;
		lockTokenUser = "0";
		messages = new Vector<String>(); //创建线程安全的消息集合
		clients = new Vector<ClientThread>();//用户线程的集合
		users = new HashMap<Integer, String>();//用户
		broadcast = new BroadCast(this);   //创建广播线程类对象
		broadcast.setFlag_exit(true);
		broadcast.start();  //启动广播类线程
		config = server.dao.queryConfigByGroupName(groupName);
		if(config != null){
			httpClientThread = new HttpClientThread(this);
			httpClientThread.setFlag_exit(true);
			httpClientThread.start();
		}
		timerManager = new TimerManager(this);
	}
	
	/**
	 * 客户端登录方法
	 ******************************************
	 * @author HuangFeng [2017年11月13日 下午5:19:50]
	 * @version 1.0
	 ******************************************
	 * @param groupName 项目组名
	 * @param username 用户名	
	 * @param clientThread 用户线程
	 */
	public void login(String groupName, String username,ClientThread clientThread) {
		try {
			// 将刚才成功连接的客户线程添加到用户集合中
			this.clients.addElement(clientThread);
			//有同名用户登录
			if (this.users.containsValue(username)) {
				for (int i = 0; i < this.clients.size(); i++) {
					int id = (int) this.clients.get(i).getId();
					if (this.users.get(id).equals(username)) {
						ClientThread client = this.clients.elementAt(i);
						this.users.remove(id);
						this.clients.removeElement(client);
						client.dos.writeUTF(client.getId()+"@forceQuit");
						client.closeClienthread();
						break;
					}
				}
			}
			this.users.put((int) clientThread.getId(), username);
	    	this.messages.addElement(getUserList());
			
			//组装当前队列信息
			StringBuffer sb = new StringBuffer();
			sb.append(clientThread.getId()+"@clientThread");
			sb.append(this.lockTokenUser+"@clientThread");
	    	for (String string : this.waitQueue) {
				sb.append(string+",");
			}
	    	sb.append("@queue@clientThread");
	    	if(config != null){
	    		sb.append(config.getGitLabUrl()+"@clientThread");
	    		sb.append(config.getSonarUrl()+"@clientThread");
	    	}else{
	    		sb.append("https://git.cae.com/"+"@clientThread");
	    		sb.append("http://gdssonar.paas.x/dashboard?id=com.travelsky.dit%3Adit"+"@clientThread");
	    	}
	    	String msg = new String(sb);
	    	clientThread.dos.writeUTF(msg);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 停止服务器
	 ******************************************
	 * @author HuangFeng [2017年7月5日 下午12:56:48]
	 * @version 1.0
	 ******************************************
	 */
	public void stopServerThread() {
		try {
			httpClientThread.setFlag_exit(false);
			broadcast.setFlag_exit(false);
			timerManager.stopTimerManager();
			server.serverThreadList.remove(groupName);
			this.server = null;
			this.clients = null;
			this.config = null;
			this.broadcast = null;
			this.httpClientThread = null;
			this.timerManager = null;
			this.users = null;
			this.finalize();
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	/**
	 * 添加等待队列
	 ******************************************
	 * @author HuangFeng [2017年7月4日 下午5:52:31]
	 * @version 1.0
	 ******************************************
	 * @param username 用户名
	 */
	public void addWaitQueue(String username){
		synchronized (waitQueue) {
			if(!waitQueue.contains(username)){
				waitQueue.add(username);
			}
		}
	}
	
	/**
	 * 移除等待队列
	 ******************************************
	 * @author HuangFeng [2017年7月4日 下午5:54:34]
	 * @version 1.0
	 ******************************************
	 * @param username 用户名
	 */
	public void removeWaitQueue(String username){
		synchronized (waitQueue) {
			waitQueue.remove(username);
		}
	}

	/**
	 * 清除断开连接的客户端
	 ******************************************
	 * @author HuangFeng [2017年11月3日 下午4:07:23]
	 * @version 1.0
	 ******************************************
	 * @param lostConnection 对象
	 */
	public void clearLostConnection(List<ClientThread> lostConnection){
		try {
			//存在断开连接的客户端
			if(!lostConnection.isEmpty()){
				for (ClientThread client : lostConnection) {
					int id = (int) client.getId();
					if(this.users.get(id).equals(this.lockTokenUser)){
						this.lockTokenUser = "0";
					}
					this.removeWaitQueue(this.users.get(id));
					this.clients.removeElement(client);
					this.users.remove(id);
					client.closeClienthread();
				}
				StringBuffer sb = new StringBuffer();
				String userlist = this.getUserList();
				ClientThread clientThread;
				for (int i = 0; i < this.clients.size(); i++) {
					String mes = "";
					clientThread = this.clients.elementAt(i);
					//更新用户列表
					clientThread.dos.writeUTF(userlist);
					//更新排队队列
					sb = new StringBuffer();
	            	for (String string : this.waitQueue) {
						sb.append(string+",");
					}
	            	sb.append("@queue");
	            	mes = new String(sb);
	            	clientThread.dos.writeUTF(mes);
	            	//更新锁定者
	            	sb = new StringBuffer();
					sb.append("@releaseToken"+this.lockTokenUser);
					mes = new String(sb);
	            	clientThread.dos.writeUTF(mes);
				}
				lostConnection.clear();
			}
		} catch (Exception e) {}
	}
	
	/**
	 * 返回当前用户列表
	 ******************************************
	 * @author HuangFeng [2017年11月3日 下午4:49:26]
	 * @version 1.0
	 ******************************************
	 * @return 用户列表
	 */
	public String getUserList(){
		StringBuffer sb = new StringBuffer();
		if(this.clients != null){
			for (int i = 0; i < this.clients.size(); i++) {
				int threadID = (int) this.clients.elementAt(i).getId();
				String name = (String) this.users.get(new Integer(threadID));
				sb.append(name + "@userlist");
				sb.append(threadID + "@userlist");
			}
		}
		return new String(sb);
	}
	
}
